Our night sky is filled with billions of galaxies, each with billions of stars. With new technoly we are able to make telescopes that can probe even the farthest of the galaxies that were born just after the big bang. But analysing all the night sky is very difficult so we have to pick out targets wisely. I propose a pipeline where the telescope data can be fed in and it will automatically classify the object based on their morphology or spectrum or anything that can be useful for the scientists. So here i have created the most crutial step of the pipeline, the classifier.
The original Galaxy10 dataset was created with Galaxy Zoo (GZ) Data Release 2 where volunteers classify ~270k of SDSS galaxy images where ~22k of those images were selected in 10 broad classes using volunteer votes. GZ later utilized images from DESI Legacy Imaging Surveys (DECals) with much better resolution and image quality. Galaxy10 DECals has combined all three (GZ DR2 with DECals images instead of SDSS images and DECals campaign ab, c) results in ~441k of unique galaxies covered by DECals where ~18k of those images were selected in 10 broad classes using volunteer votes with more rigorous filtering. Galaxy10 DECals had its 10 broad classes tweaked a bit so that each class is more distinct from each other and Edge-on Disk with Boxy Bulge class with only 17 images in original Galaxy10 was abandoned. The source code for this dataset is released under this repositary so you are welcome to play around if you like, otherwise you can use the compiled Galaxy10 DECals with dowload link below.
Galaxy10_DECals.h5: https://astro.utoronto.ca/~hleung/shared/Galaxy10/Galaxy10_DECals.h5
Galaxy10 DECals is a dataset contains 17736 256x256 pixels colored galaxy images (g, r and z band) separated in 10 classes. Galaxy10_DECals.h5 have columns images with shape (17736, 256, 256, 3), ans, ra, dec, redshift and pxscale in unit of arcsecond per pixel
!pip install h5py
Requirement already satisfied: h5py in c:\users\user\anaconda3\lib\site-packages (3.2.1) Requirement already satisfied: numpy>=1.19.0 in c:\users\user\anaconda3\lib\site-packages (from h5py) (1.20.3)
import h5py
import numpy as np
from tensorflow.keras import utils
The data is stored in .h5 file format. So here I am using h5py library to open the image data and storing it in a numpy array.
with h5py.File('../Data/Galaxy10_DECals.h5','r') as F:
images = np.array(F['images'])
labels = np.array(F['ans'])
import PIL
import matplotlib.pyplot as plt
import random
label_names = ['Disturbed Galaxy',
'Merging Galaxy',
'Round Smooth Galaxy',
'In-between Round Smooth Galaxy',
'Cigar Shaped Smooth Galaxy',
'Barred Spiral Galaxy',
'Unbarred Tight Spiral Galaxy',
'Unbarred Loose Spiral Galaxy',
'Edge-on Galaxy without Bulge',
'Edge-on Galaxy with Bulge'
]
Here I have selected 16 images randomly from the dataset and they are displayed using matplotlib.pyplot.imshow.
plt.figure(figsize=(13,13))
for i in range(16):
index = random.randint(0,17736)
image = images[index]
plt.subplot(4,4,i + 1)
plt.imshow(image)
plt.title(label_names[labels[index]])
plt.axis('off')
labels.shape
(17736,)
Here I have used sci-kit learn library to split the numpy data into training and testing set. The ratio of training and testing set is 5:1.
from sklearn.model_selection import train_test_split
train_idx, test_idx = train_test_split(np.arange(labels.shape[0]), test_size = 0.2)
train_images, train_labels, test_images, test_labels = images[train_idx], labels[train_idx], images[test_idx], labels[test_idx]
print(train_images.shape[0], test_images.shape[0])
14188 3548
images.shape
(17736, 256, 256, 3)
import tensorflow as tf
img_height = 256
img_width = 256
class_names = label_names
train_dataset = tf.data.Dataset.from_tensor_slices((train_images, train_labels))
test_dataset = tf.data.Dataset.from_tensor_slices((test_images, test_labels))
BATCH_SIZE = 50
SHUFFLE_BUFFER_SIZE = 1000
train_dataset = train_dataset.shuffle(SHUFFLE_BUFFER_SIZE).batch(BATCH_SIZE)
test_dataset = test_dataset.batch(BATCH_SIZE)
EPOCHS = 5
The RGB channel values are in the [0, 255] range. This is not ideal for a neural network; in general we should seek to make your input values small.
Here, I have standardize values to be in the [0, 1] range by using tf.keras.layers.Rescaling:
AUTOTUNE = tf.data.AUTOTUNE
train_dataset = train_dataset.cache().shuffle(1000).prefetch(buffer_size=AUTOTUNE)
test_dataset = test_dataset.cache().prefetch(buffer_size=AUTOTUNE)
from tensorflow.keras import layers
normalization_layer = layers.Rescaling(1./255)
normalized_dataset = train_dataset.map(lambda x,y: (normalization_layer(x),y))
images_batch, labels_batch = next(iter(normalized_dataset))
num_classes = len(class_names)
The Sequential model consists of three convolution blocks (tf.keras.layers.Conv2D) with a max pooling layer (tf.keras.layers.MaxPooling2D) in each of them. There's a fully-connected layer (tf.keras.layers.Dense) with 128 units on top of it that is activated by a ReLU activation function ('relu'). This model has not been tuned for high accuracy—the goal of this tutorial is to show a standard approach.
Below is an image to understand how neural network works, but instead of classifying animals we are classifying galaxies.
from tensorflow.keras.models import Sequential
model = Sequential([
layers.Rescaling(1./255, input_shape=(img_height, img_width, 3)),
layers.Conv2D(16, 3, padding='same', activation='relu'),
layers.MaxPooling2D(),
layers.Conv2D(32, 3, padding='same', activation='relu'),
layers.MaxPooling2D(),
layers.Conv2D(64, 3, padding='same', activation='relu'),
#layers.MaxPooling2D(),
#layers.Conv2D(128, 3, padding='same', activation='relu'),
layers.MaxPooling2D(),
layers.Flatten(),
layers.Dense(128, activation='relu'),
layers.Dense(num_classes)
])
--------------------------------------------------------------------------- NameError Traceback (most recent call last) ~\AppData\Local\Temp/ipykernel_15724/2819146983.py in <module> 1 from tensorflow.keras.models import Sequential 2 model = Sequential([ ----> 3 layers.Rescaling(1./255, input_shape=(img_height, img_width, 3)), 4 layers.Conv2D(16, 3, padding='same', activation='relu'), 5 layers.MaxPooling2D(), NameError: name 'layers' is not defined
model.compile(optimizer='adam', loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True),metrics=['accuracy'])
--------------------------------------------------------------------------- NameError Traceback (most recent call last) ~\AppData\Local\Temp/ipykernel_15724/3352606015.py in <module> ----> 1 model.compile(optimizer='adam', loss='binary_crossentropy',metrics=['accuracy']) NameError: name 'model' is not defined
Here you can se all the hidden layers and their shapes, and total numbers of parameters after each layers is also shown.
model.summary()
Model: "sequential"
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
rescaling_1 (Rescaling) (None, 256, 256, 3) 0
conv2d (Conv2D) (None, 256, 256, 16) 448
max_pooling2d (MaxPooling2D (None, 128, 128, 16) 0
)
conv2d_1 (Conv2D) (None, 128, 128, 32) 4640
max_pooling2d_1 (MaxPooling (None, 64, 64, 32) 0
2D)
conv2d_2 (Conv2D) (None, 64, 64, 64) 18496
max_pooling2d_2 (MaxPooling (None, 32, 32, 64) 0
2D)
flatten (Flatten) (None, 65536) 0
dense (Dense) (None, 128) 8388736
dense_1 (Dense) (None, 10) 1290
=================================================================
Total params: 8,413,610
Trainable params: 8,413,610
Non-trainable params: 0
_________________________________________________________________
I haved trained the model for 5 epochs to see how the model behaves.
EPOCHS = 5
history = model.fit(
train_dataset,
validation_data = test_dataset,
epochs = EPOCHS
)
Epoch 1/5 284/284 [==============================] - 20s 49ms/step - loss: 2.0042 - accuracy: 0.2447 - val_loss: 1.7909 - val_accuracy: 0.3174 Epoch 2/5 284/284 [==============================] - 13s 44ms/step - loss: 1.6224 - accuracy: 0.4007 - val_loss: 1.4915 - val_accuracy: 0.4501 Epoch 3/5 284/284 [==============================] - 13s 44ms/step - loss: 1.2760 - accuracy: 0.5389 - val_loss: 1.4778 - val_accuracy: 0.4749 Epoch 4/5 284/284 [==============================] - 13s 44ms/step - loss: 1.0344 - accuracy: 0.6324 - val_loss: 1.3889 - val_accuracy: 0.5172 Epoch 5/5 284/284 [==============================] - 13s 45ms/step - loss: 0.8017 - accuracy: 0.7198 - val_loss: 1.4810 - val_accuracy: 0.5285
acc = history.history['accuracy']
val_acc = history.history['val_accuracy']
loss = history.history['loss']
val_loss = history.history['val_loss']
epochs_range = range(EPOCHS)
plt.figure(figsize=(8, 8))
plt.subplot(1, 2, 1)
plt.plot(epochs_range, acc, label='Training Accuracy')
plt.plot(epochs_range, val_acc, label='Validation Accuracy')
plt.legend(loc='lower right')
plt.title('Training and Validation Accuracy')
plt.subplot(1, 2, 2)
plt.plot(epochs_range, loss, label='Training Loss')
plt.plot(epochs_range, val_loss, label='Validation Loss')
plt.legend(loc='upper right')
plt.title('Training and Validation Loss')
plt.show()
In the plots above, the training accuracy is increasing linearly over time, whereas validation accuracy stalls around 60% in the training process. Also, the difference in accuracy between training and validation accuracy is noticeable—a sign of overfitting.
When there are a small number of training examples, the model sometimes learns from noises or unwanted details from training examples—to an extent that it negatively impacts the performance of the model on new examples. This phenomenon is known as overfitting. It means that the model will have a difficult time generalizing on a new dataset.
There are multiple ways to fight overfitting in the training process.
Here I have used a barred spiral galaxy image and the model is able to pridict it correctly, But not always. We need to improve the model.
from tensorflow import keras
from tensorflow.keras import utils
barred_spiral_img = tf.keras.utils.load_img('../Data/new_test_data/barred_spiral_test1.png', target_size = (img_height, img_width))
PIL.Image.open('../Data/new_test_data/barred_spiral_test1.png')
img_array = tf.keras.utils.img_to_array(barred_spiral_img)
img_array = tf.expand_dims(img_array, 0)
prediction = model.predict(img_array)
score = tf.nn.softmax(prediction[0])
for i in score: print(i)
tf.Tensor(0.07197627, shape=(), dtype=float32) tf.Tensor(0.059918653, shape=(), dtype=float32) tf.Tensor(0.0040735723, shape=(), dtype=float32) tf.Tensor(0.0020373825, shape=(), dtype=float32) tf.Tensor(4.951063e-06, shape=(), dtype=float32) tf.Tensor(0.77023846, shape=(), dtype=float32) tf.Tensor(0.0071348613, shape=(), dtype=float32) tf.Tensor(0.08411451, shape=(), dtype=float32) tf.Tensor(8.2698214e-05, shape=(), dtype=float32) tf.Tensor(0.00041850048, shape=(), dtype=float32)
print('This galaxy is most likely to be a ' + str(class_names[np.argmax(score)]) + '.')
This galaxy is most likely to be a Barred Spiral Galaxy.
Overfitting generally occurs when there are a small number of training examples. Data augmentation takes the approach of generating additional training data from your existing examples by augmenting them using random transformations that yield believable-looking images. This helps expose the model to more aspects of the data and generalize better.
I will implement data augmentation using the following Keras preprocessing layers: tf.keras.layers.RandomFlip, tf.keras.layers.RandomRotation, tf.keras.layers.RandomTranslation, and tf.keras.layers.RandomZoom. These can be included inside your model like other layers, and run on the GPU.
zoom_factor = (-0.1,0.5)
data_augmentation = Sequential([
layers.RandomFlip('horizontal_and_vertical',input_shape=(img_height, img_width, 3)),
layers.RandomRotation(0.5),
#layers.RandomZoom(height_factor=zoom_factor, width_factor=zoom_factor),
layers.RandomZoom((-0.5,0.1),fill_mode='wrap'),
layers.RandomTranslation(0.08,0.08)#, fill_mode='wrap')
])
plt.figure(figsize=(10, 10))
for images, _ in train_dataset.take(1):
for i in range(9):
augmented_images = data_augmentation(images)
ax = plt.subplot(3, 3, i + 1)
plt.imshow(augmented_images[0].numpy().astype("uint8"))
plt.axis("off")
model = Sequential([
data_augmentation,
layers.Rescaling(1./255, input_shape=(img_height, img_width, 3)),
layers.Conv2D(16, 3, padding='same', activation='relu'),
layers.MaxPooling2D(),
layers.Conv2D(32, 3, padding='same', activation='relu'),
layers.MaxPooling2D(),
layers.Conv2D(64, 3, padding='same', activation='relu'),
layers.MaxPooling2D(),
layers.Conv2D(128, 3, padding='same', activation='relu'),
layers.MaxPooling2D(),
layers.Dropout(0.2),
layers.Flatten(),
layers.Dense(256, activation='relu'),
layers.Flatten(),
layers.Dense(128, activation='relu'),
layers.Dense(num_classes)
])
model.compile(optimizer='adam', loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True),
metrics=['accuracy'])
EPOCHS = 100
model.summary()
Model: "sequential_2"
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
sequential_1 (Sequential) (None, 256, 256, 3) 0
rescaling_2 (Rescaling) (None, 256, 256, 3) 0
conv2d_3 (Conv2D) (None, 256, 256, 16) 448
max_pooling2d_3 (MaxPooling (None, 128, 128, 16) 0
2D)
conv2d_4 (Conv2D) (None, 128, 128, 32) 4640
max_pooling2d_4 (MaxPooling (None, 64, 64, 32) 0
2D)
conv2d_5 (Conv2D) (None, 64, 64, 64) 18496
max_pooling2d_5 (MaxPooling (None, 32, 32, 64) 0
2D)
conv2d_6 (Conv2D) (None, 32, 32, 128) 73856
max_pooling2d_6 (MaxPooling (None, 16, 16, 128) 0
2D)
dropout (Dropout) (None, 16, 16, 128) 0
flatten_1 (Flatten) (None, 32768) 0
dense_2 (Dense) (None, 256) 8388864
flatten_2 (Flatten) (None, 256) 0
dense_3 (Dense) (None, 128) 32896
dense_4 (Dense) (None, 10) 1290
=================================================================
Total params: 8,520,490
Trainable params: 8,520,490
Non-trainable params: 0
_________________________________________________________________
history = model.fit(train_dataset,
validation_data= test_dataset,
epochs=EPOCHS)
Epoch 1/100 284/284 [==============================] - 19s 60ms/step - loss: 1.9943 - accuracy: 0.2505 - val_loss: 1.8324 - val_accuracy: 0.3126 Epoch 2/100 284/284 [==============================] - 16s 57ms/step - loss: 1.6606 - accuracy: 0.3771 - val_loss: 1.4974 - val_accuracy: 0.4462 Epoch 3/100 284/284 [==============================] - 16s 58ms/step - loss: 1.4607 - accuracy: 0.4538 - val_loss: 1.4886 - val_accuracy: 0.4346 Epoch 4/100 284/284 [==============================] - 16s 57ms/step - loss: 1.3698 - accuracy: 0.4922 - val_loss: 1.3908 - val_accuracy: 0.4963 Epoch 5/100 284/284 [==============================] - 16s 58ms/step - loss: 1.2978 - accuracy: 0.5245 - val_loss: 1.3375 - val_accuracy: 0.5025 Epoch 6/100 284/284 [==============================] - 16s 57ms/step - loss: 1.2314 - accuracy: 0.5522 - val_loss: 1.1787 - val_accuracy: 0.5753 Epoch 7/100 284/284 [==============================] - 17s 59ms/step - loss: 1.1405 - accuracy: 0.5870 - val_loss: 1.0567 - val_accuracy: 0.6198 Epoch 8/100 284/284 [==============================] - 17s 59ms/step - loss: 1.0823 - accuracy: 0.6128 - val_loss: 1.0248 - val_accuracy: 0.6370 Epoch 9/100 284/284 [==============================] - 16s 57ms/step - loss: 1.0062 - accuracy: 0.6427 - val_loss: 0.9466 - val_accuracy: 0.6719 Epoch 10/100 284/284 [==============================] - 16s 58ms/step - loss: 0.9776 - accuracy: 0.6563 - val_loss: 0.9351 - val_accuracy: 0.6702 Epoch 11/100 284/284 [==============================] - 16s 58ms/step - loss: 0.9364 - accuracy: 0.6711 - val_loss: 1.0565 - val_accuracy: 0.6234 Epoch 12/100 284/284 [==============================] - 16s 57ms/step - loss: 0.9026 - accuracy: 0.6841 - val_loss: 0.9389 - val_accuracy: 0.6719 Epoch 13/100 284/284 [==============================] - 16s 58ms/step - loss: 0.8915 - accuracy: 0.6855 - val_loss: 0.8972 - val_accuracy: 0.6843 Epoch 14/100 284/284 [==============================] - 16s 58ms/step - loss: 0.8698 - accuracy: 0.6958 - val_loss: 0.8073 - val_accuracy: 0.7145 Epoch 15/100 284/284 [==============================] - 16s 57ms/step - loss: 0.8608 - accuracy: 0.6990 - val_loss: 0.8737 - val_accuracy: 0.6908 Epoch 16/100 284/284 [==============================] - 16s 58ms/step - loss: 0.8342 - accuracy: 0.7108 - val_loss: 0.7918 - val_accuracy: 0.7252 Epoch 17/100 284/284 [==============================] - 16s 58ms/step - loss: 0.8382 - accuracy: 0.7084 - val_loss: 0.8312 - val_accuracy: 0.7134 Epoch 18/100 284/284 [==============================] - 16s 57ms/step - loss: 0.8208 - accuracy: 0.7125 - val_loss: 0.8034 - val_accuracy: 0.7103 Epoch 19/100 284/284 [==============================] - 16s 58ms/step - loss: 0.8000 - accuracy: 0.7198 - val_loss: 0.7638 - val_accuracy: 0.7283 Epoch 20/100 284/284 [==============================] - 16s 57ms/step - loss: 0.7873 - accuracy: 0.7236 - val_loss: 0.7911 - val_accuracy: 0.7275 Epoch 21/100 284/284 [==============================] - 16s 58ms/step - loss: 0.7922 - accuracy: 0.7236 - val_loss: 0.8206 - val_accuracy: 0.7066 Epoch 22/100 284/284 [==============================] - 16s 58ms/step - loss: 0.7693 - accuracy: 0.7328 - val_loss: 0.7656 - val_accuracy: 0.7325 Epoch 23/100 284/284 [==============================] - 16s 57ms/step - loss: 0.7663 - accuracy: 0.7311 - val_loss: 0.7168 - val_accuracy: 0.7497 Epoch 24/100 284/284 [==============================] - 16s 58ms/step - loss: 0.7605 - accuracy: 0.7326 - val_loss: 0.6867 - val_accuracy: 0.7630 Epoch 25/100 284/284 [==============================] - 16s 57ms/step - loss: 0.7606 - accuracy: 0.7374 - val_loss: 0.7477 - val_accuracy: 0.7410 Epoch 26/100 284/284 [==============================] - 16s 57ms/step - loss: 0.7391 - accuracy: 0.7431 - val_loss: 0.7636 - val_accuracy: 0.7356 Epoch 27/100 284/284 [==============================] - 16s 58ms/step - loss: 0.7460 - accuracy: 0.7389 - val_loss: 0.7563 - val_accuracy: 0.7444 Epoch 28/100 284/284 [==============================] - 16s 58ms/step - loss: 0.7384 - accuracy: 0.7372 - val_loss: 0.7704 - val_accuracy: 0.7418 Epoch 29/100 284/284 [==============================] - 16s 57ms/step - loss: 0.7229 - accuracy: 0.7502 - val_loss: 0.7855 - val_accuracy: 0.7266 Epoch 30/100 284/284 [==============================] - 16s 57ms/step - loss: 0.7243 - accuracy: 0.7507 - val_loss: 0.6959 - val_accuracy: 0.7610 Epoch 31/100 284/284 [==============================] - 17s 59ms/step - loss: 0.7193 - accuracy: 0.7513 - val_loss: 0.7416 - val_accuracy: 0.7362 Epoch 32/100 284/284 [==============================] - 16s 57ms/step - loss: 0.7179 - accuracy: 0.7496 - val_loss: 0.6834 - val_accuracy: 0.7596 Epoch 33/100 284/284 [==============================] - 16s 57ms/step - loss: 0.7061 - accuracy: 0.7549 - val_loss: 0.6591 - val_accuracy: 0.7675 Epoch 34/100 284/284 [==============================] - 16s 57ms/step - loss: 0.7047 - accuracy: 0.7555 - val_loss: 0.6575 - val_accuracy: 0.7765 Epoch 35/100 284/284 [==============================] - 16s 56ms/step - loss: 0.7041 - accuracy: 0.7561 - val_loss: 0.6487 - val_accuracy: 0.7754 Epoch 36/100 284/284 [==============================] - 16s 57ms/step - loss: 0.6906 - accuracy: 0.7558 - val_loss: 0.6476 - val_accuracy: 0.7740 Epoch 37/100 284/284 [==============================] - 18s 63ms/step - loss: 0.6845 - accuracy: 0.7633 - val_loss: 0.7185 - val_accuracy: 0.7466 Epoch 38/100 284/284 [==============================] - 18s 62ms/step - loss: 0.6854 - accuracy: 0.7600 - val_loss: 0.6829 - val_accuracy: 0.7582 Epoch 39/100 284/284 [==============================] - 17s 59ms/step - loss: 0.6828 - accuracy: 0.7610 - val_loss: 0.6975 - val_accuracy: 0.7565 Epoch 40/100 284/284 [==============================] - 17s 60ms/step - loss: 0.6824 - accuracy: 0.7656 - val_loss: 0.6842 - val_accuracy: 0.7610 Epoch 41/100 284/284 [==============================] - 17s 61ms/step - loss: 0.6882 - accuracy: 0.7599 - val_loss: 0.6943 - val_accuracy: 0.7599 Epoch 42/100 284/284 [==============================] - 17s 58ms/step - loss: 0.6627 - accuracy: 0.7673 - val_loss: 0.6877 - val_accuracy: 0.7604 Epoch 43/100 284/284 [==============================] - 17s 58ms/step - loss: 0.6714 - accuracy: 0.7685 - val_loss: 0.6208 - val_accuracy: 0.7807 Epoch 44/100 284/284 [==============================] - 17s 59ms/step - loss: 0.6729 - accuracy: 0.7642 - val_loss: 0.6468 - val_accuracy: 0.7604 Epoch 45/100 284/284 [==============================] - 17s 58ms/step - loss: 0.6615 - accuracy: 0.7680 - val_loss: 0.6372 - val_accuracy: 0.7807 Epoch 46/100 284/284 [==============================] - 17s 58ms/step - loss: 0.6658 - accuracy: 0.7668 - val_loss: 0.6231 - val_accuracy: 0.7821 Epoch 47/100 284/284 [==============================] - 17s 58ms/step - loss: 0.6541 - accuracy: 0.7764 - val_loss: 0.6657 - val_accuracy: 0.7666 Epoch 48/100 284/284 [==============================] - 17s 58ms/step - loss: 0.6495 - accuracy: 0.7694 - val_loss: 0.6753 - val_accuracy: 0.7658 Epoch 49/100 284/284 [==============================] - 17s 58ms/step - loss: 0.6536 - accuracy: 0.7712 - val_loss: 0.6315 - val_accuracy: 0.7830 Epoch 50/100 284/284 [==============================] - 17s 58ms/step - loss: 0.6534 - accuracy: 0.7731 - val_loss: 0.6324 - val_accuracy: 0.7802 Epoch 51/100 284/284 [==============================] - 17s 58ms/step - loss: 0.6466 - accuracy: 0.7731 - val_loss: 0.6493 - val_accuracy: 0.7725 Epoch 52/100 284/284 [==============================] - 17s 58ms/step - loss: 0.6367 - accuracy: 0.7821 - val_loss: 0.6161 - val_accuracy: 0.7858 Epoch 53/100 284/284 [==============================] - 17s 58ms/step - loss: 0.6413 - accuracy: 0.7770 - val_loss: 0.6303 - val_accuracy: 0.7804 Epoch 54/100 284/284 [==============================] - 17s 58ms/step - loss: 0.6445 - accuracy: 0.7716 - val_loss: 0.6459 - val_accuracy: 0.7714 Epoch 55/100 284/284 [==============================] - 17s 58ms/step - loss: 0.6366 - accuracy: 0.7788 - val_loss: 0.6468 - val_accuracy: 0.7697 Epoch 56/100 284/284 [==============================] - 17s 58ms/step - loss: 0.6306 - accuracy: 0.7773 - val_loss: 0.6397 - val_accuracy: 0.7762 Epoch 57/100 284/284 [==============================] - 17s 58ms/step - loss: 0.6301 - accuracy: 0.7778 - val_loss: 0.6298 - val_accuracy: 0.7872 Epoch 58/100 284/284 [==============================] - 17s 58ms/step - loss: 0.6260 - accuracy: 0.7826 - val_loss: 0.5936 - val_accuracy: 0.7976 Epoch 59/100 284/284 [==============================] - 17s 58ms/step - loss: 0.6268 - accuracy: 0.7818 - val_loss: 0.6049 - val_accuracy: 0.7872 Epoch 60/100 284/284 [==============================] - 17s 58ms/step - loss: 0.6243 - accuracy: 0.7804 - val_loss: 0.6380 - val_accuracy: 0.7754 Epoch 61/100 284/284 [==============================] - 17s 58ms/step - loss: 0.6248 - accuracy: 0.7824 - val_loss: 0.6213 - val_accuracy: 0.7787 Epoch 62/100 284/284 [==============================] - 17s 58ms/step - loss: 0.6209 - accuracy: 0.7828 - val_loss: 0.6150 - val_accuracy: 0.7785 Epoch 63/100 284/284 [==============================] - 17s 59ms/step - loss: 0.6202 - accuracy: 0.7854 - val_loss: 0.6322 - val_accuracy: 0.7796 Epoch 64/100 284/284 [==============================] - 16s 57ms/step - loss: 0.6105 - accuracy: 0.7845 - val_loss: 0.6160 - val_accuracy: 0.7810 Epoch 65/100 284/284 [==============================] - 16s 57ms/step - loss: 0.6212 - accuracy: 0.7828 - val_loss: 0.6229 - val_accuracy: 0.7796 Epoch 66/100 284/284 [==============================] - 16s 56ms/step - loss: 0.6128 - accuracy: 0.7871 - val_loss: 0.6167 - val_accuracy: 0.7813 Epoch 67/100 284/284 [==============================] - 16s 57ms/step - loss: 0.6111 - accuracy: 0.7873 - val_loss: 0.6239 - val_accuracy: 0.7799 Epoch 68/100 284/284 [==============================] - 17s 58ms/step - loss: 0.6084 - accuracy: 0.7864 - val_loss: 0.6170 - val_accuracy: 0.7866 Epoch 69/100 284/284 [==============================] - 16s 58ms/step - loss: 0.6074 - accuracy: 0.7880 - val_loss: 0.6549 - val_accuracy: 0.7692 Epoch 70/100 284/284 [==============================] - 16s 58ms/step - loss: 0.6097 - accuracy: 0.7894 - val_loss: 0.5852 - val_accuracy: 0.7943 Epoch 71/100 284/284 [==============================] - 16s 58ms/step - loss: 0.6080 - accuracy: 0.7903 - val_loss: 0.6243 - val_accuracy: 0.7855 Epoch 72/100 284/284 [==============================] - 16s 58ms/step - loss: 0.6028 - accuracy: 0.7869 - val_loss: 0.6059 - val_accuracy: 0.7841 Epoch 73/100 284/284 [==============================] - 16s 58ms/step - loss: 0.5994 - accuracy: 0.7902 - val_loss: 0.6334 - val_accuracy: 0.7768 Epoch 74/100 284/284 [==============================] - 16s 58ms/step - loss: 0.5952 - accuracy: 0.7910 - val_loss: 0.5726 - val_accuracy: 0.7982 Epoch 75/100 284/284 [==============================] - 17s 59ms/step - loss: 0.5985 - accuracy: 0.7918 - val_loss: 0.6444 - val_accuracy: 0.7737 Epoch 76/100 284/284 [==============================] - 18s 62ms/step - loss: 0.5987 - accuracy: 0.7885 - val_loss: 0.5933 - val_accuracy: 0.7931 Epoch 77/100 284/284 [==============================] - 17s 58ms/step - loss: 0.6092 - accuracy: 0.7862 - val_loss: 0.5981 - val_accuracy: 0.7943 Epoch 78/100 284/284 [==============================] - 16s 58ms/step - loss: 0.5978 - accuracy: 0.7874 - val_loss: 0.6671 - val_accuracy: 0.7641 Epoch 79/100 284/284 [==============================] - 16s 58ms/step - loss: 0.5880 - accuracy: 0.7952 - val_loss: 0.5966 - val_accuracy: 0.7985 Epoch 80/100 284/284 [==============================] - 16s 58ms/step - loss: 0.5882 - accuracy: 0.7918 - val_loss: 0.6077 - val_accuracy: 0.7776 Epoch 81/100 284/284 [==============================] - 16s 58ms/step - loss: 0.5889 - accuracy: 0.7942 - val_loss: 0.6490 - val_accuracy: 0.7754 Epoch 82/100 284/284 [==============================] - 16s 58ms/step - loss: 0.5898 - accuracy: 0.7931 - val_loss: 0.6343 - val_accuracy: 0.7751 Epoch 83/100 284/284 [==============================] - 16s 58ms/step - loss: 0.5894 - accuracy: 0.7945 - val_loss: 0.6090 - val_accuracy: 0.7864 Epoch 84/100 284/284 [==============================] - 16s 58ms/step - loss: 0.5803 - accuracy: 0.7982 - val_loss: 0.6500 - val_accuracy: 0.7740 Epoch 85/100 284/284 [==============================] - 16s 58ms/step - loss: 0.5770 - accuracy: 0.7982 - val_loss: 0.6145 - val_accuracy: 0.7923 Epoch 86/100 284/284 [==============================] - 16s 58ms/step - loss: 0.5802 - accuracy: 0.7957 - val_loss: 0.6062 - val_accuracy: 0.7883 Epoch 87/100 284/284 [==============================] - 16s 58ms/step - loss: 0.5881 - accuracy: 0.7919 - val_loss: 0.6129 - val_accuracy: 0.7869 Epoch 88/100 284/284 [==============================] - 16s 58ms/step - loss: 0.5846 - accuracy: 0.7941 - val_loss: 0.6099 - val_accuracy: 0.7835 Epoch 89/100 284/284 [==============================] - 17s 58ms/step - loss: 0.5767 - accuracy: 0.7969 - val_loss: 0.6226 - val_accuracy: 0.7787 Epoch 90/100 284/284 [==============================] - 16s 58ms/step - loss: 0.5823 - accuracy: 0.7962 - val_loss: 0.5737 - val_accuracy: 0.7968 Epoch 91/100 284/284 [==============================] - 16s 58ms/step - loss: 0.5737 - accuracy: 0.8006 - val_loss: 0.5902 - val_accuracy: 0.7982 Epoch 92/100 284/284 [==============================] - 16s 58ms/step - loss: 0.5799 - accuracy: 0.7972 - val_loss: 0.6021 - val_accuracy: 0.7883 Epoch 93/100 284/284 [==============================] - 17s 59ms/step - loss: 0.5721 - accuracy: 0.8010 - val_loss: 0.6244 - val_accuracy: 0.7818 Epoch 94/100 284/284 [==============================] - 17s 58ms/step - loss: 0.5713 - accuracy: 0.8026 - val_loss: 0.5846 - val_accuracy: 0.7951 Epoch 95/100 284/284 [==============================] - 16s 58ms/step - loss: 0.5666 - accuracy: 0.8008 - val_loss: 0.5867 - val_accuracy: 0.7982 Epoch 96/100 284/284 [==============================] - 16s 58ms/step - loss: 0.5731 - accuracy: 0.7983 - val_loss: 0.6190 - val_accuracy: 0.7841 Epoch 97/100 284/284 [==============================] - 16s 58ms/step - loss: 0.5640 - accuracy: 0.8029 - val_loss: 0.6175 - val_accuracy: 0.7880 Epoch 98/100 284/284 [==============================] - 16s 58ms/step - loss: 0.5673 - accuracy: 0.7991 - val_loss: 0.5932 - val_accuracy: 0.7883 Epoch 99/100 284/284 [==============================] - 16s 58ms/step - loss: 0.5717 - accuracy: 0.7993 - val_loss: 0.5865 - val_accuracy: 0.7931 Epoch 100/100 284/284 [==============================] - 17s 58ms/step - loss: 0.5702 - accuracy: 0.8024 - val_loss: 0.5872 - val_accuracy: 0.7928
acc = history.history['accuracy']
val_acc = history.history['val_accuracy']
loss = history.history['loss']
val_loss = history.history['val_loss']
epochs_range = range(EPOCHS)
plt.figure(figsize=(8, 8))
plt.subplot(1, 2, 1)
plt.plot(epochs_range, acc, label='Training Accuracy')
plt.plot(epochs_range, val_acc, label='Validation Accuracy')
plt.legend(loc='lower right')
plt.title('Training and Validation Accuracy')
plt.subplot(1, 2, 2)
plt.plot(epochs_range, loss, label='Training Loss')
plt.plot(epochs_range, val_loss, label='Validation Loss')
plt.legend(loc='upper right')
plt.title('Training and Validation Loss')
plt.show()
prediction = model.predict(img_array)
score = tf.nn.softmax(prediction[0])
for i in score: print(i)
tf.Tensor(0.031662643, shape=(), dtype=float32) tf.Tensor(1.3360906e-05, shape=(), dtype=float32) tf.Tensor(1.7445062e-05, shape=(), dtype=float32) tf.Tensor(9.918027e-09, shape=(), dtype=float32) tf.Tensor(1.1274198e-11, shape=(), dtype=float32) tf.Tensor(0.96132505, shape=(), dtype=float32) tf.Tensor(6.0916893e-05, shape=(), dtype=float32) tf.Tensor(0.006852181, shape=(), dtype=float32) tf.Tensor(7.145125e-07, shape=(), dtype=float32) tf.Tensor(6.769257e-05, shape=(), dtype=float32)
print('This galaxy is most likely to be a ' + str(class_names[np.argmax(score)]) + '.')
This galaxy is most likely to be a Barred Spiral Galaxy.
i = 5
test_img = tf.keras.utils.load_img(f'../Data/new_test_data/galaxy_test_{i}.png', target_size = (img_height, img_width))
disp_img = PIL.Image.open(f'../Data/new_test_data/galaxy_test_{i}.png')
#disp_img.resize((img_height, img_width))
size = (img_height, img_width)
disp_img.thumbnail(size, PIL.Image.ANTIALIAS)
disp_img
img_array = tf.keras.utils.img_to_array(test_img)
img_array = tf.expand_dims(img_array, 0)
img_array.shape
TensorShape([1, 256, 256, 3])
prediction = model.predict(img_array)
score = tf.nn.softmax(prediction[0])
for i in score: print(i)
tf.Tensor(0.029760612, shape=(), dtype=float32) tf.Tensor(0.00096607377, shape=(), dtype=float32) tf.Tensor(0.0001968926, shape=(), dtype=float32) tf.Tensor(0.0004474812, shape=(), dtype=float32) tf.Tensor(0.0014142577, shape=(), dtype=float32) tf.Tensor(0.6551534, shape=(), dtype=float32) tf.Tensor(0.010337954, shape=(), dtype=float32) tf.Tensor(0.051949665, shape=(), dtype=float32) tf.Tensor(0.10332805, shape=(), dtype=float32) tf.Tensor(0.14644569, shape=(), dtype=float32)
print('This galaxy is most likely to be a ' + str(class_names[np.argmax(score)]) + '.')
This galaxy is most likely to be a Barred Spiral Galaxy.
class_names
['Disturbed Galaxy', 'Merging Galaxy', 'Round Smooth Galaxy', 'In-between Round Smooth Galaxy', 'Cigar Shaped Smooth Galaxy', 'Barred Spiral Galaxy', 'Unbarred Tight Spiral Galaxy', 'Unbarred Loose Spiral Galaxy', 'Edge-on Galaxy without Bulge', 'Edge-on Galaxy with Bulge']